#include "CJudge.h"
/*  向8个方向搜索，0为向上、1为右上、2为向右、3为右下
                                        4为向下、5为左下、6为向左、7为左上 */
CJudge::CJudge()
{
        result = 0;
}
CJudge::~CJudge()
{
}
int CJudge::JudgeWin(CBoard b, int judge_player, int judge_x, int judge_y)
{
        int same[8] = {0}; //不同方向相邻连续相同颜色棋子数
        /*考虑最后落子为玩家一，搜索*/
        if (judge_player == PLAYER1)
        {

                /*向左搜索*/
                int i = judge_x, j = judge_y - 1;
                while (j >= 0 && b.board[i][j] == BLACK)
                {
                        j--;
                        same[0]++;
                }
                /*左下搜索*/
                i = judge_x + 1, j = judge_y - 1;
                while (i < 15 && j >= 0 && b.board[i][j] == BLACK)
                {
                        i++;
                        j--;
                        same[1]++;
                }
                /*向下搜索*/
                i = judge_x + 1, j = judge_y;
                while (i < 15 && b.board[i][j] == BLACK)
                {
                        i++;
                        same[2]++;
                }
                /*右下搜索*/
                i = judge_x + 1, j = judge_y + 1;
                while (i < 15 && j < 15 && b.board[i][j] == BLACK)
                {
                        i++;
                        j++;
                        same[3]++;
                }
                /*向右搜索*/
                i = judge_x, j = judge_y + 1;
                while (i < 15 && b.board[i][j] == BLACK)
                {
                        j++;
                        same[4]++;
                }
                /*右上搜索*/
                i = judge_x - 1, j = judge_y + 1;
                while (i >= 0 && j < 15 && b.board[i][j] == BLACK)
                {
                        i--;
                        j++;
                        same[5]++;
                }
                /*向上搜索*/
                i = judge_x - 1, j = judge_y;
                while (i >= 0 && b.board[i][j] == BLACK)
                {
                        i--;
                        same[6]++;
                }
                /*左上搜索*/
                i = judge_x - 1, j = judge_y - 1;
                while (i >= 0 && j >= 0 && b.board[i][j] == BLACK)
                {
                        i--;
                        j--;
                        same[7]++;
                }
                i = judge_x, j = judge_y;
        }
        /*最后落子为玩家二，搜索*/
        else if (judge_player == PLAYER2)
        {
                /*向左搜索*/
                int i = judge_x, j = judge_y - 1;
                while (j >= 0 && b.board[i][j] == WHITE)
                {
                        j--;
                        same[0]++;
                }
                /*左下搜索*/
                i = judge_x + 1, j = judge_y - 1;
                while (i < 15 && j >= 0 && b.board[i][j] == WHITE)
                {
                        i++;
                        j--;
                        same[1]++;
                }
                /*向下搜索*/
                i = judge_x + 1, j = judge_y;
                while (i < 15 && b.board[i][j] == WHITE)
                {
                        i++;
                        same[2]++;
                }
                /*右下搜索*/
                i = judge_x + 1, j = judge_y + 1;
                while (i < 15 && j < 15 && b.board[i][j] == WHITE)
                {
                        i++;
                        j++;
                        same[3]++;
                }
                /*向右搜索*/
                i = judge_x, j = judge_y + 1;
                while (i < 15 && b.board[i][j] == WHITE)
                {
                        i++;
                        same[4]++;
                }
                /*右上搜索*/
                i = judge_x - 1, j = judge_y + 1;
                while (i >= 0 && j < 15 && b.board[i][j] == WHITE)
                {
                        i--;
                        j++;
                        same[5]++;
                }
                /*向上搜索*/
                i = judge_x - 1, j = judge_y;
                while (i >= 0 && b.board[i][j] == WHITE)
                {
                        i--;
                        same[6]++;
                }
                /*左上搜索*/
                i = judge_x - 1, j = judge_y - 1;
                while (i >= 0 && j >= 0 && b.board[i][j] == WHITE)
                {
                        i--;
                        j--;
                        same[7]++;
                }
                i = judge_x, j = judge_y;
        }
        /*判断*/
        int l = 0;
        while (l < 4)
        {
                if (same[l] + same[l + 4] == 4) //五子相连
                {
                        return WIN;
                }
                l++;
        }
        return 0;
}

int CJudge::ForbiddenJudge(CBoard b, int judge_x, int judge_y)
{
        judge_x--, judge_y--;
        int threecount = 0; //活三
        int fourcount = 0;
        /*活四，这里因为是用来做第一层判断是否为四四的，生命周期等于函数的生命周期
        不能使用静态变量，后面递归检验一个方向三三需要判断左右两点是否为四，单独创建新的静态变量如下：*/
        static int double_fourcount = 0; //活四
        static int single_fourcount = 0; //冲四
        int same[8] = {0};               //不同方向相邻连续相同颜色棋子数
        /*搜索判断禁手点各向信息*/
        /*向左搜索*/
        int i = judge_x, j = judge_y - 1;
        while (j >= 0 && b.board[i][j] == BLACK)
        {
                j--;
                same[0]++;
        }

        /*左下搜索*/
        i = judge_x + 1, j = judge_y - 1;

        while (i < 15 && j >= 0 && b.board[i][j] == BLACK)
        {
                i++;
                j--;
                same[1]++;
        }

        /*向下搜索*/
        i = judge_x + 1, j = judge_y;

        while (i < 15 && b.board[i][j] == BLACK)
        {
                i++;
                same[2]++;
        }

        /*右下搜索*/
        i = judge_x + 1, j = judge_y + 1;

        while (i < 15 && j < 15 && b.board[i][j] == BLACK)
        {
                i++;
                j++;
                same[3]++;
        }

        /*向右搜索*/
        i = judge_x, j = judge_y + 1;

        while (i < 15 && b.board[i][j] == BLACK)
        {
                j++;
                same[4]++;
        }

        /*右上搜索*/
        i = judge_x - 1, j = judge_y + 1;

        while (i >= 0 && j < 15 && b.board[i][j] == BLACK)
        {
                i--;
                j++;
                same[5]++;
        }

        /*向上搜索*/
        i = judge_x - 1, j = judge_y;

        while (i >= 0 && b.board[i][j] == BLACK)
        {
                i--;
                same[6]++;
        }

        /*左上搜索*/
        i = judge_x - 1, j = judge_y - 1;

        while (i >= 0 && j >= 0 && b.board[i][j] == BLACK)
        {
                i--;
                j--;
                same[7]++;
        }

        /*搜索结束，开始判断禁手*/
        i = judge_x, j = judge_y;
        int l = 0;
        while (l < 4)
        {
                if (same[l] + same[l + 4] >= 5) /*长连判断*/
                {
                        return CHANGLIAN_FORBIDDEN;
                }
                else if (same[l] + same[l + 4] == 4) //五子相连
                {
                        return WIN;
                }

                else if (same[l] + same[l + 4] == 3) //四子相连
                {
                        /*判断冲四活四*/
                        int key_x, key_y; //小于4一侧关键点坐标
                        int key_m, key_n;
                        same[l]++; //相隔点数加一，用于计算关键点坐标
                        same[l + 4]++;
                        /*计算关键点坐标*/
                        switch (l % 4)
                        {
                        case 0:
                                key_x = judge_x;
                                key_y = judge_y - same[l];
                                key_m = judge_x;
                                key_n = judge_y + same[l + 4];
                                break;
                        case 1:
                                key_x = judge_x + same[l];
                                key_y = judge_y - same[l];
                                key_m = judge_x - same[l + 4];
                                key_n = judge_y + same[l + 4];
                                break;
                        case 2:
                                key_x = judge_x + same[l];
                                key_y = judge_y;
                                key_m = judge_x - same[l + 4];
                                key_n = judge_y;
                                break;
                        default:
                                key_x = judge_x + same[l];
                                key_y = judge_y + same[l];
                                key_m = judge_x - same[l + 4];
                                key_n = judge_y - same[l + 4];
                                break;
                        }
                        b.board[judge_x][judge_y] = 1;
                        /*递归调用函数*/
                        int judge_0123 = 0, judge_4567 = 0;       //区分活四、冲四、为静态变量赋值，供检验活三时使用静态变量做准备
                        if (key_x < 15 && key_x >= 0 && key_y < 15 && key_y >= 0 && b.board[key_x][key_y] == 0) //判断是否可下
                        {
                                judge_0123 = ForbiddenJudge(b, key_x + 1, key_y + 1); //l<4判断
                        }

                        if (key_m < 15 && key_m >= 0 && key_n < 15 && key_n >= 0 && b.board[key_m][key_n] == 0)
                        {
                                judge_4567 = ForbiddenJudge(b, key_m + 1, key_n + 1); //l>3判断
                        }

                        /*恢复棋盘*/
                        b.board[judge_x][judge_y] = 0;
                        if (judge_0123 == WIN && judge_4567 == WIN)
                        {
                                double_fourcount++;
                        }
                        else if (judge_0123 == WIN || judge_4567 == WIN)
                        {
                                single_fourcount++;
                        }
                        fourcount = single_fourcount + double_fourcount;
                }

                else if (same[l] + same[l + 4] == 2) //三子相连
                {
                        int key_x, key_y; //小于4一侧关键点坐标
                        int key_m, key_n;
                        same[l]++; //相隔点数加一，用于计算关键点坐标
                        same[l + 4]++;
                        /*计算关键点坐标*/
                        switch (l % 4)
                        {
                        case 0:
                                key_x = judge_x;
                                key_y = judge_y - same[l];
                                key_m = judge_x;
                                key_n = judge_y + same[l + 4];
                                break;
                        case 1:
                                key_x = judge_x + same[l];
                                key_y = judge_y - same[l];
                                key_m = judge_x - same[l + 4];
                                key_n = judge_y + same[l + 4];
                                break;
                        case 2:
                                key_x = judge_x + same[l];
                                key_y = judge_y;
                                key_m = judge_x - same[l + 4];
                                key_n = judge_y;
                                break;
                        default:
                                key_x = judge_x + same[l];
                                key_y = judge_y + same[l];
                                key_m = judge_x - same[l + 4];
                                key_n = judge_y - same[l + 4];
                                break;
                        }
                        /*活四检查*/
                        b.board[judge_x][judge_y] = 1;
                        /*递归调用函数*/
                        //int judge_0123 = 0, judge_4567 = 0;//有用吗？用统计活四个数还是用返回值？
                        if (key_x < 15 && key_x >= 0 && key_y < 15 && key_y >= 0 && b.board[key_x][key_y] == 0) //判断是否可下
                        {
                                //judge_0123 = ForbiddenJudge(b, key_x + 1, key_y + 1); //l<4判断
                                ForbiddenJudge(b, key_x + 1, key_y + 1);
                        }
                        if (key_m < 15 && key_m >= 0 && key_n < 15 && key_n >= 0 && b.board[key_m][key_n] == 0)
                        {
                                // judge_4567 = ForbiddenJudge(b, key_m + 1, key_n + 1); //l>3判断
                                ForbiddenJudge(b, key_m + 1, key_n + 1);
                        }

                        /*恢复棋盘*/
                        b.board[judge_x][judge_y] = 0;
                        if (double_fourcount > 0)
                        {
                                threecount++;
                        }
                        double_fourcount = 0; //使用递归判断一个方向活三，判断完成后，清除假设，不能出现递归层的假设内容：四子相连
                        single_fourcount = 0;
                }
                /*l方向禁手分析结束*/
                l++;
                /*判断活三*/
        }
        /*判断活三、冲四、活四是否满足禁手*/
        if (fourcount > 1)
        {
                return DOUBLE_FOUR_FORBIDDEN;
        }
        if (threecount > 1)
        {
                return DOUBLE_THREE_FORBIDDEN;
        }
        return NO_FORBIDDEN;
}